package services;

import domain.entities.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Guillermo
 * Date: 09/08/12
 * Time: 15:10
 * To change this template use File | Settings | File Templates.
 */
@Service
public class CentralVendorCRUDService implements CRUDService<Vendorcentral>{

    private VendorcentralDAO vendorcentralDAO;
    private AddressService addressService;
    private ProtocoloCompromisopaisService protocoloCompromisopaisService;
    private VendorTypeService vendorTypeService;

    public CentralVendorCRUDService() {
    }

    @Autowired
    public CentralVendorCRUDService(VendorcentralDAO vendorcentralDAO, AddressService addressService, ProtocoloCompromisopaisService protocoloCompromisopaisService, VendorTypeService vendorTypeService) {
        this.vendorcentralDAO = vendorcentralDAO;
        this.addressService = addressService;
        this.protocoloCompromisopaisService = protocoloCompromisopaisService;
        this.vendorTypeService = vendorTypeService;
    }


    public <V extends Criteria> List<Vendorcentral> list(V criteria) {
        List<Vendorcentral> list = vendorcentralDAO.findAll();
        Iterator<Vendorcentral> it = list.iterator();
        while(it.hasNext()){
            if(!criteria.isIn(it.next())){
                it.remove();
            }
        }
        return list;
    }

    public void save(Vendorcentral vendorcentral){
        vendorcentralDAO.attachDirty((domain.entities.Vendorcentral) vendorcentral);
    }

    public void merge(Vendorcentral vendorcentral){
        vendorcentralDAO.merge((domain.entities.Vendorcentral) vendorcentral);
    }

    public Vendorcentral findById(int id){
        return (Vendorcentral) vendorcentralDAO.findById(id);
    }

    public void delete(Vendorcentral vendorcentral) {
        vendorcentralDAO.deleteById(((domain.entities.Vendorcentral) vendorcentral).getId());
    }

    public List<Vendorcentral> findAllByProtocoloCompromisoPais(ProtocoloCompromisopais protocoloCompromisopais) {
        List<Vendorcentral> vendors = vendorcentralDAO.findAll();
        Iterator<Vendorcentral> it = vendors.iterator();
        while(it.hasNext()){
            Vendorcentral vc = it.next();
            Set<ProtocoloCompromisopais> misProtocolos = new HashSet<ProtocoloCompromisopais>(vc.getProtocolos());
            if(vc.getProtocolos()==null
                    ||
               vc.getProtocolos().size()==0
                    ||
               !misProtocolos.contains(protocoloCompromisopais) ){
                it.remove();
            }
        }
        return vendors;
    }

    public List<Vendorcentral> findAllLocalVendorsByProtocoloCompromisoPais(ProtocoloCompromisopais protocoloCompromisopais){
        List<Vendorcentral> list = findAllByProtocoloCompromisoPais(protocoloCompromisopais);
        Iterator<Vendorcentral> it = list.iterator();
        while(it.hasNext()){
            Vendorcentral v = it.next();
            if(!v.getCategory().equals(Vendorcentral.LOCAL_CATEGORY)){
                it.remove();
            }
        }
        return list;
    }

    public List<Vendorcentral> findAllCentralVendors() {
        List<Vendorcentral> list = vendorcentralDAO.findAll();
        Iterator<Vendorcentral> it = list.iterator();
        while (it.hasNext()){
            Vendorcentral vc = it.next();
            if(!vc.getCategory().equals(Vendorcentral.CENTRAL_CATEGORY)){
                it.remove();
            }
        }
        return list;
    }

    public List<Vendorcentral> findAllCentralVendorsByProtocolo(Protocolo protocolo) {
        List<Vendorcentral> list = new ArrayList<Vendorcentral>();

        if(protocolo == null || protocolo.getId().isEmpty()){
            return list;
        }

        list = findAllCentralVendors();
        Iterator<Vendorcentral> it = list.iterator();
        while (it.hasNext()){
            Vendorcentral vc = it.next();
            if(
                    vc.getProtocolos() == null
                  ||
                    vc.getProtocolos().size()==0
                  ||
                    vc.getProtocolos().get(0).getProtocolo() == null
                  ||
                    !vc.getProtocolos().get(0).getProtocolo().equals(protocolo)
            ){
                it.remove();
            }

        }
        return list;
    }

    public List<Vendorcentral> listByNameAndCategoryAndType(String name, String category,Integer vendorTypeId) {
        Vendorcentral vc = new Vendorcentral();
        VendorType vt = null;
        if(vendorTypeId != null){
            vt = vendorTypeService.findbyId(vendorTypeId);
            vc.setType(vt);
        }
        vc.setName(name);
        vc.setCategory(category);
        Criteria cr = new CriteriaByName(vc);

        return list(cr);
    }

    public void saveGlobalVendor(Vendorcentral vendor, Protocolo protocolo) {
        Vendorcentral persisted = vendorcentralDAO.findById(vendor.getId());

        /*Set new data to already created object*/
        _deepcopy(vendor,persisted);

        vendorcentralDAO.merge(persisted);
    }

    public void saveLocalVendor(Vendorcentral vendor, ProtocoloCompromisopais protocolo) {
        List<ProtocoloCompromisopais> protocolos = new ArrayList<ProtocoloCompromisopais>();
        protocolos.add(protocolo);

        vendor.setProtocolos(protocolos);
        Vendorcentral persisted = vendorcentralDAO.findById(vendor.getId());

        /*Set new data to already created object*/
        _deepcopy(vendor,persisted);

        vendorcentralDAO.merge(persisted);
    }

    private void _deepcopy(Vendorcentral source, Vendorcentral dest) {
        dest.setContactPerson(source.getContactPerson());
        dest.setSecondaryContactPerson(source.getSecondaryContactPerson());
        dest.setProtocolos(source.getProtocolos());
        dest.setSites(source.getSites());
    }

    private class CriteriaByName extends Criteria{

        private Vendorcentral vendor;

        public CriteriaByName(Vendorcentral vendor) {
            this.vendor = vendor;
        }

        @Override
        public boolean isIn(Object element){
            boolean isIn = true;

            Vendorcentral other = (Vendorcentral)element;
            boolean p1 =isSubstring(vendor.getName(),other.getName());
            boolean p2 = vendor.getCategory().equals(other.getCategory());
            boolean p3 = vendor.getType() == null || vendor.getType().equals(other.getType());
            isIn = p1 && p2 && p3;

            return isIn;
        }
    }
}
